/**
 * Created by Administrator on 2025/5/7.
 * */
#include "AIE2EMonitor.h"
#include <iostream>
#include <thread>

BaseObject *createAIE2EMonitor() {
    return new AIE2EMonitor();
}

void destroyAIE2EMonitor(BaseObject *p) {
    SAFE_DELETE(p);
}

AIE2EMonitor::AIE2EMonitor() : clearOutput1(false) {
    prevStep = -1;
    // 订阅数据源主题Topic
    sub = zmq::socket_t(context, zmq::socket_type::sub);
    sub.connect(topicAddr.c_str());
    sub.set(zmq::sockopt::subscribe, topicName);
}

AIE2EMonitor::~AIE2EMonitor() {
}

/* 如果使用了DDS_Reader或者DDS_Writer，则对应的input或者output前64个字节为DataFormat head首部 */
void AIE2EMonitor::onCompute(buffer_table_t *input, buffer_table_t *output) {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    int step;
    zmq::message_t msgTopicName;
    zmq::message_t msgData;
    if (!sub.recv(msgTopicName, zmq::recv_flags::none)) {
        std::cerr << "Subscribe: Failed to receive topic name" << std::endl;
    }
    std::string topicName_(static_cast<char*>(msgTopicName.data()), msgTopicName.size());
    if (!sub.recv(msgData, zmq::recv_flags::none)) {
        std::cerr << "Subscribe: Failed to receive data" << std::endl;
    }
    memcpy(&step, msgData.data(), sizeof(float));
    if (prevStep == step) {
        return ;
    }
    prevStep = step;
    if (clearOutput1) {
        // 通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState使其开始训练
        int *pAIE2ENetState = reinterpret_cast<int*>(output->list[1]->data);
        *pAIE2ENetState = 0; // Vtt_notify
        clearOutput1 = false;
        return ;
    }
    // 根据全局aiE2EState确定相应的操作
    int aiE2EMonitorState = GlobalParameters::shareInstance()->get_parameter_aiE2EMonitorState(dynamic_cast<TaskModule*>(this));
    if (aiE2EMonitorState==static_cast<int>(AIE2EMonitorStateEnum::Runing)) {
        std::cout << "AIE2EInfer::AIE2EMonitor: 开始比较端到端算法与传统算法 v0.0.1" << std::endl;
        // 使AIE2EMonitor开始工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Notify_Tat);
    }
    if (aiE2EMonitorState==static_cast<int>(AIE2EMonitorStateEnum::Notify_Tat) && step==STEP7) {
        std::cout << "AIE2EInfer::AIE2EMonitor: 识别到端到端算法与传统算法有差异，通知AIE2ETrain::AIE2ENet开始训练" << std::endl;
        // 停止AIE2EMonitor工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Vtt);
        // 通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState到Tat_Model_Notify，以使AIE2ETrain::AIE2ENet开始传统算法辅助训练
        int *pAIE2ENetState = reinterpret_cast<int*>(output->list[1]->data);
        *pAIE2ENetState = 4; // Tat_Notify
    }
    if (aiE2EMonitorState==static_cast<int>(AIE2EMonitorStateEnum::Vtt) && step>STEP7) {
        // 通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState到Tat_Model_Notify，以使AIE2ETrain::AIE2ENet开始传统算法辅助训练
        int *pAIE2ENetState = reinterpret_cast<int*>(output->list[1]->data);
        *pAIE2ENetState = 0; // Tat_Notify
    }
    // 虚拟真值学习
    if (step == STEP10) {
        std::cout << "AIE2EInfer::AIE2EMonitor: 模型未能识别出虚拟真值目标，通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState以开始训练" << std::endl;
        // 停止AIE2EMonitor工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Vtt);
        // 通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState使其开始训练
        int *pAIE2ENetState = reinterpret_cast<int*>(output->list[1]->data);
        *pAIE2ENetState = 7; // Vtt_notify
        clearOutput1 = true;
    }
    if (aiE2EMonitorState==static_cast<int>(AIE2EMonitorStateEnum::Vtt) && step>STEP10) {
        // 停止AIE2EMonitor工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Sst_Ready);
    }
    // 自监督学习
    if (aiE2EMonitorState==static_cast<int>(AIE2EMonitorStateEnum::Sst_Notify)) {
        // 停止AIE2EMonitor工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Sst_Notified);
        // 通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState使其开始训练
        int *pAIE2ENetState = reinterpret_cast<int*>(output->list[1]->data);
        *pAIE2ENetState = 10; // Sst_notify
        clearOutput1 = true;
    }
    if (aiE2EMonitorState==static_cast<int>(AIE2EMonitorStateEnum::Sst_Notified)) {
        // 停止AIE2EMonitor工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Sst_Idle);
        // 通知AIE2ETrain::AIE2ETrainController更新全局状态aiE2ENetState使其进入自监督学习模式
        int *pAIE2ENetState = reinterpret_cast<int*>(output->list[1]->data);
        *pAIE2ENetState = 0; // Sst_notify
    }
}
